package com.tianxiao.faas.biz.service.corner;

import com.google.common.collect.Lists;
import com.tianxiao.faas.api.param.corner.ArticleResult;
import com.tianxiao.faas.api.param.corner.ArticleSaveParam;
import com.tianxiao.faas.api.param.corner.BasePageParam;
import com.tianxiao.faas.common.util.Base64Utils;
import com.tianxiao.faas.common.util.DateUtils;
import com.tianxiao.faas.common.util.ImageUtils;
import com.tianxiao.faas.common.util.LikeQueryUtils;
import com.tianxiao.faas.common.util.PageUtils;
import com.tianxiao.faas.mapper.dao.ArticleModelMapper;
import com.tianxiao.faas.mapper.dao.ShopArticleModelMapper;
import com.tianxiao.faas.mapper.model.ArticleModel;
import com.tianxiao.faas.mapper.model.ShopArticleModel;
import com.tianxiao.faas.mapper.model.ShopArticleModelExample;
import com.tianxiao.faas.mapper.model.ShopModel;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ArticleService {
    @Resource
    private ArticleModelMapper articleModelMapper;
    @Resource
    private ShopArticleModelMapper shopArticleModelMapper;
    @Resource
    private ShopService shopService;

    @Transactional(rollbackFor = Throwable.class)
    public void save(ArticleSaveParam param, Long userId, Integer type) {
        Long id = param.getId();
        ArticleModel record = new ArticleModel();
        String content = param.getContent();
        if (content != null) {
            String encode = Base64Utils.encode(content);
            record.setContent(encode);
        }
        record.setCoverImg(param.getImg());
        long created = System.currentTimeMillis();
        record.setId(id);
        record.setTitle(param.title());
        record.setType(type);
        record.setUpdated(created);
        record.setEditor(userId);
        if (id == null) {
            record.setUserId(userId);
            record.setDeleted(0);
            record.setCreated(created);
            articleModelMapper.insertSelective(record);
            if (param.getShopId() != null) {
                ShopArticleModel shopArticleModel = new ShopArticleModel();
                shopArticleModel.setShopId(param.getShopId());
                shopArticleModel.setArticleId(record.getId());
                shopArticleModel.setDeleted(0);
                shopArticleModelMapper.insertSelective(shopArticleModel);
            }
        } else {
            if (param.getShopId() != null) {
                ShopArticleModelExample example = new ShopArticleModelExample();
                example.createCriteria()
                        .andArticleIdEqualTo(id)
                        .andDeletedEqualTo(0);
                List<ShopArticleModel> shopArticleModels =
                        shopArticleModelMapper.selectByExample(example);
                if (!CollectionUtils.isEmpty(shopArticleModels)) {
                    ShopArticleModel shopArticleModel = shopArticleModels.get(0);
                    shopArticleModel.setShopId(param.getShopId());
                    shopArticleModelMapper.updateByPrimaryKeySelective(shopArticleModel);
                } else {
                    ShopArticleModel shopArticleModel = new ShopArticleModel();
                    shopArticleModel.setShopId(param.getShopId());
                    shopArticleModel.setArticleId(record.getId());
                    shopArticleModel.setDeleted(0);
                    shopArticleModelMapper.insertSelective(shopArticleModel);
                }
            }
            articleModelMapper.updateByPrimaryKeySelective(record);
        }
    }

    public void delete(Long id, Long userId) {
        ArticleModel articleModel = new ArticleModel();
        articleModel.setId(id);
        articleModel.setEditor(userId);
        articleModel.setUpdated(System.currentTimeMillis());
        articleModel.setDeleted(1);
        articleModelMapper.updateByPrimaryKeySelective(articleModel);
    }

    public void publish(Long id, Long userId, Integer type) {
        ArticleModel articleModel = new ArticleModel();
        articleModel.setId(id);
        articleModel.setType(type);
        articleModel.setEditor(userId);
        articleModel.setUpdated(System.currentTimeMillis());
        articleModelMapper.updateByPrimaryKeySelective(articleModel);
    }

    public Integer count(BasePageParam param, List<Integer> types) {
        String key = param.getKey();
        String key1 = LikeQueryUtils.getKey(key);
        return articleModelMapper.count(key1, types);
    }

    public List<ArticleResult> page(BasePageParam param, boolean needShop, List<Integer> types) {
        String key = param.getKey();
        String key1 = LikeQueryUtils.getKey(key);
        Integer pageSize = param.getPageSize();
        Integer offset = PageUtils.getOffset(param.getPage(), pageSize);
        List<ArticleModel> page = articleModelMapper.page(key1, types,offset, pageSize);
        if (CollectionUtils.isEmpty(page)) {
            return Lists.newArrayList();
        }
        List<Long> articleIds = page.stream().map(ArticleModel::getId).collect(Collectors.toList());
        ShopArticleModelExample example = new ShopArticleModelExample();
        example.createCriteria().andArticleIdIn(articleIds).andDeletedEqualTo(0);
        List<ShopArticleModel> shopArticleModels = shopArticleModelMapper.selectByExample(example);
        Map<Long, ShopModel> shopModelMap = new HashMap<>();
        Map<Long, ShopArticleModel> articleModelMap = new HashMap<>();
        if (needShop) {
            List<Long> collect = shopArticleModels.stream().map(ShopArticleModel::getShopId).collect(Collectors.toList());
            List<ShopModel> shopModels = shopService.listByIds(collect);
            shopModelMap = shopModels.stream().collect(Collectors.toMap(ShopModel::getId, s -> s, (key3, key2) -> key3));
            articleModelMap = shopArticleModels.stream()
                    .collect(Collectors.toMap(ShopArticleModel::getArticleId, s -> s, (key3, key2) -> key3));
        }
        List<ArticleResult> data = new ArrayList<>();
        for (ArticleModel model : page) {
            ArticleResult result = getArticleResult(shopModelMap, articleModelMap, model);
            data.add(result);
        }
        return data;
    }

    public ArticleResult get(Long id) {
        ArticleModel model = articleModelMapper.selectByPrimaryKey(id);
        return getArticleResult(model);
    }


    private ArticleResult getArticleResult(ArticleModel model) {
        return getArticleResult(new HashMap<>(1), new HashMap<>(1), model);
    }

    private ArticleResult getArticleResult(Map<Long, ShopModel> shopModelMap, Map<Long, ShopArticleModel> articleModelMap, ArticleModel model) {
        ArticleResult result = new ArticleResult();
        String content = model.getContent();
        result.setContent(Base64Utils.decode(content));
        result.setCreateTime(DateUtils.format(model.getCreated()));
        result.setId(model.getId());
        String coverImg = model.getCoverImg();
        result.setImg(coverImg);
        result.setIsImage(coverImg == null ? true : ImageUtils.isImage(coverImg));
        result.init(model.getTitle());
        result.setPublish((model.getType() ==1 || model.getType() == 3));
        ShopArticleModel shopArticleModel = articleModelMap.get(model.getId());
        if (shopArticleModel != null) {
            Long shopId = shopArticleModel.getShopId();
            ShopModel shopModel = shopModelMap.get(shopId);
            result.setShopName(shopModel == null ? "" : shopModel.getName());
        }
        result.setUpdateTime(DateUtils.format(model.getUpdated()));
        return result;
    }
}
